Skip to content

feat: persistent CLI configuration with layered resolution#2

Merged
broomva merged 6 commits intomainfrom
feat/persistent-cli-config
Mar 1, 2026
Merged

feat: persistent CLI configuration with layered resolution#2
broomva merged 6 commits intomainfrom
feat/persistent-cli-config

Conversation

@broomva
Copy link
Owner

@broomva broomva commented Mar 1, 2026

Summary

  • Add TOML-based two-layer config system: file-based config for pre-daemon bootstrap (provider, model, port), Lago SessionManifest for post-daemon agent context
  • New CLI commands: arcan config init/set/get/list, arcan status, arcan stop
  • New global flags --provider and --model; --port now optional with config fallback
  • Resolution chain: hardcoded defaults → global config (~/.config/arcan/config.toml) → project-local config (.arcan/config.toml) → env vars → CLI flags
  • Provider construction refactored with from_resolved() constructors that accept config overrides while always reading API keys from env vars (never from config file)
  • 10 new tests for config module (merge, set/get, resolve, serialization roundtrip, save/load)

Example Usage

# One-time setup
arcan config init
arcan config set provider ollama
arcan config set model gpt-oss:20b
arcan config set port 3001

# Now just:
arcan run "What is 2+2?"                       # uses config defaults
arcan run "Hello" --provider mock              # CLI flag overrides
ARCAN_PROVIDER=anthropic arcan run "Hello"     # env var overrides

# Daemon management
arcan status                                   # provider, model, port, daemon status
arcan stop                                     # graceful shutdown

Files Changed

File Change
NEW: crates/arcan/src/config.rs Config structs, loading, merging, saving, ResolvedConfig
crates/arcan/src/main.rs Add mod config, global flags, Config/Status/Stop commands, refactored provider selection
crates/arcan/src/daemon.rs Forward provider/model to daemon spawn, public helpers, stop_daemon()
crates/arcan/src/cli_run.rs Accept optional model param, propagate into session creation
crates/arcan/Cargo.toml Add toml, dirs deps
Cargo.toml (workspace) Add toml, dirs to workspace deps
crates/arcan-provider/src/anthropic.rs Add from_resolved() constructor
crates/arcan-provider/src/openai.rs Add openai_from_resolved(), ollama_from_resolved() constructors

Test plan

  • cargo fmt && cargo clippy --workspace -- -D warnings passes
  • cargo test --workspace — 246 tests passing (+1 ignored)
  • cargo build --workspace succeeds
  • Manual: arcan config init && arcan config set provider mock && arcan config list
  • Manual: arcan status shows resolved config
  • Manual: arcan run "Hello" --provider mock (CLI override)
  • Manual: arcan stop graceful shutdown

🤖 Generated with Claude Code

broomva and others added 6 commits March 1, 2026 00:21
Add TOML-based config system with two-layer design:
- Layer 1: TOML config file (.arcan/config.toml) for pre-daemon settings
- Layer 2: Lago SessionManifest for post-daemon agent context

Resolution chain: hardcoded defaults → global config → project-local
config → env vars → CLI flags.

New CLI commands:
- `arcan config init/set/get/list` — manage persistent configuration
- `arcan status` — show provider, model, port, daemon status
- `arcan stop` — graceful daemon shutdown via SIGTERM

New global flags: --provider, --model (--port now Optional).

Provider construction refactored to use from_resolved() constructors
that accept config overrides while always reading API keys from env vars.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The arcan workspace has path dependencies to ../aiOS/ and ../lago/
which are sibling repos in the monorepo. CI was failing because these
weren't available. Now each job clones them with --depth 1.

Also fixes MSRV check from 1.80.0 to 1.85.0 (Rust 2024 edition).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix 3 pre-existing clippy lints caught by newer stable clippy:
  needless borrow in context.rs test, len comparison in
  context_compiler.rs test, unnecessary closure in runtime.rs test
- Fix 2 clippy lints in config.rs tests (field_reassign_with_default)
- Update deny.toml for cargo-deny v2 schema (remove deprecated keys)
- Bump MSRV check to 1.88.0 (transitive deps require it)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Migrate [advisories] and [licenses] to version 2 format.
Remove deprecated keys (vulnerability, unlicensed) — these are
now deny-by-default in v2.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The cargo-deny-action runs in a Docker container which can't
see the sibling ../aiOS and ../lago directories. Switch to
installing cargo-deny directly and running it on the host.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add license.workspace = true to arcan-tui Cargo.toml (was missing)
- Ignore RUSTSEC-2024-0436 (paste unmaintained) — transitive dep
  from ratatui, no action until upstream migrates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@broomva broomva merged commit 2f4e0a6 into main Mar 1, 2026
8 checks passed
@broomva broomva deleted the feat/persistent-cli-config branch March 1, 2026 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant